using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Mbs.Collections;
using Mbs.Log;

namespace Mbs.Modularity.AddIns
{ 
    [Serializable]
    [DebuggerDisplay("Path={Path},Label={Label},AddInName={AddInName}")]
    internal class AddInItemPath : IAddInItemPath
    {

        private static ILog logger = LoggerManager.Instance.CreateLogger(typeof(AddInItemPath));

        public string AddInName { get; private set; }
        public bool BuildStartUp { get; set; }
        public string Label { get; set; }
        public string Path { get; private set; }
        public string ParentPath { get; private set; }

        public IAddInItemCollection Items { get; private set; }
        public IPropertySet Properties { get; private set; }
       
        private AddInItemPath() { }

        internal AddInItemPath(string  addInName, string path, string label)
        {
            this.AddInName = addInName;
            this.Path = path;
            this.Label = label;

            Items = new AddInItemCollection();

            int pos = path.LastIndexOf('/');
            if (pos != -1)
                ParentPath = path.Substring(0, pos);
        }

        public IAddInNode Clone()
        {
            var o = new AddInItemPath();

            o.AddInName = AddInName;
            o.BuildStartUp = BuildStartUp;
            o.Path = Path;
            o.Label = Label;
            o.ParentPath = ParentPath;

            o.Items = Items.Clone();

            o.Properties = Properties;

            return o;
        }

       
        object ICloneable.Clone()
        {
            return Clone();
        }

        public object Build(object owner)
        {
            List<object> rs = new List<object>();

            foreach (var item in Items)
                rs.Add(item.Build(owner));

            return rs;
        }



        internal static void SetUp(AddInItemPath exPath, Mbs.Configuration.INode node)
        {
            if (exPath == null)
                throw new ArgumentNullException("exPath");
            if (string.IsNullOrEmpty(exPath.Path))
                throw new ArgumentNullException("exPath.Path");

            logger.Debug("parse addin item path，" + exPath.Path + " in addin :" + exPath.AddInName);

            exPath.Properties = node.Attributes;
            SetUpChildElement(node, exPath);
        }

        private static void SetUpChildElement(Mbs.Configuration.INode node, IAddInNode parent)
        {
           // Stack<ICondition> conditionStack = new Stack<ICondition>();
            foreach (var subNode in node.Nodes)
            {
                //if (subNode.Id == "Condition")
                //    conditionStack.Push(new Condition(subNode.Id, subNode.Attributes));
                //else if (subNode.Id == "ComplexCondition")
                //    conditionStack.Push(new ComplexCondition(subNode.Id, subNode));
                //else
                {
                    //List<ICondition> conditions = new List<ICondition>();
                    //conditions.AddRange(conditionStack.ToArray());

                    if (!subNode.Attributes.Contains("Id"))
                        throw new AddInLoadException();

                    var addinItem = new AddInItem(parent.AddInName, parent.Path, subNode.Attributes, subNode.Nodes.ToArray());
                    logger.Debug("　　add addin item，" + addinItem.ToString());
                    parent.Items.Add(addinItem);

                    if (subNode.Nodes.Count > 0)
                        SetUpChildElement(subNode, addinItem);
                }

            }

        }

        public override string ToString()
        {
            return string.Format("path[{0}}, label[{1}], addinName[{2}]", Path, Label, AddInName);
        }
    }
}
